package org.centsuse.intention_spring.invention.entities.contexts;

import dev.langchain4j.memory.ChatMemory;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import dev.langchain4j.store.memory.chat.InMemoryChatMemoryStore;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.centsuse.intention_spring.invention.config.scenes.Parameter;
import org.centsuse.intention_spring.invention.config.scenes.SceneConfig;
import org.centsuse.intention_spring.invention.config.scenes.SceneSlotTemplate;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import static dev.langchain4j.data.message.UserMessage.userMessage;
import static dev.langchain4j.internal.ValidationUtils.ensureNotBlank;

/**
 * 常用会话上下文
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@Slf4j
public class CommonContext implements DialogueContext {

    private static final String CHAT_MEMORY_FLAG = "common_context";

    /** 会话id */
    private String sessionId;

    /** 历史记录 */
    private ChatMemory chatMemory;

    /** 当前会话意图 */
    private String currentPurpose = "";

    /** 槽值 */
    private final Map<String, SceneSlotTemplate> slots = new ConcurrentHashMap<>();

    public CommonContext(String sessionId) {
        this.sessionId = sessionId;
    }

    @Override
    public void initSlot(SceneConfig sceneConfig) {
        slots.clear();
        if (null == sceneConfig) {
            log.warn("[CommonContext][initSlot] sceneConfig is null");
            return;
        }
        for (Parameter parameter : sceneConfig.getParameters()) {
            SceneSlotTemplate slotTemplate = new SceneSlotTemplate();
            slotTemplate.setName(parameter.getName());
            slotTemplate.setType(parameter.getType());
            slotTemplate.setDesc(parameter.getDesc());
            slotTemplate.setType(parameter.getType());
            slots.put(parameter.getName(), slotTemplate);
        }
    }

    @Override
    public void initChatMemory() {
        chatMemory = MessageWindowChatMemory.builder()
                .id(CHAT_MEMORY_FLAG)
                .maxMessages(10)
                .chatMemoryStore(new InMemoryChatMemoryStore())
                .build();
    }


    @Override
    public String getSessionId() {
        return this.sessionId;
    }

    @Override
    public String updateCurrentPurpose(String purpose) {
        this.currentPurpose = purpose;
        return purpose;
    }

    @Override
    public void updateSlot(String key, SceneSlotTemplate slotTemplate) {
        this.slots.put(key, slotTemplate);
    }

    @Override
    public String getCurrentPurpose() {
        return this.currentPurpose;
    }

    public SceneSlotTemplate getSlot(String key) {
        return this.slots.get(key);
    }

    @Override
    public void initChatMemory(ChatMemory chatMemory) {
    }

    @Override
    public void addMemory(String message) {
        chatMemory.add(userMessage(ensureNotBlank(message, "userMessage")));
    }

    @Override
    public ChatMemory getMemory() {
        return chatMemory;
    }

    @Override
    public <T> T getSlotValue(String key, Class<T> type) {
        return DialogueContext.super.getSlotValue(key, type);
    }
}
